package switcher;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Timer; // TimeTask
import java.util.TimerTask;

public abstract class AbsSwitcher {
	private int refreshTime = 50;
	private Timer timer = new Timer();

	private InetAddress serverAddr;
	private int port;

	private DatagramSocket socket;
	private DatagramPacket packet;

	private InetAddress mcaddr;
	private int mcport;
	private boolean broadcastEnabled = false;

	public AbsSwitcher(String serverName, int port, String mcAddress, int mcPort) {
		try {
			this.serverAddr = InetAddress.getByName(serverName);
			this.port = port;
			this.mcaddr = InetAddress.getByName(mcAddress);
			this.mcport = mcPort;
		} catch (Exception e) {
			System.out.println(e);
		}
	}

	public abstract void msgInterrupt(byte data[]);

	public void start() { // 开始从服务器接受消息
		System.out.printf("Switcher start.. %s:%d, \n\tMultcastAddr.. %s:%d\n",
				this.serverAddr.toString(), this.port, this.mcaddr.toString(),
				this.mcport);
		
		timer.schedule(new TimerTask() {
			@Override
			public void run() {
				try {
					send_recv();
					msgInterrupt(getData());
				} catch (Exception e) {
					System.out.println(e);
				}

			}
		}, 20, refreshTime); // 20ms后启动
	}

	public void stop() { // 停止访问和广播
		timer.cancel();
		this.destroy();
	}

	public void enableBroadcast() {
		this.broadcastEnabled = true;
	}

	public int getRefreshTime() {
		return refreshTime;
	}

	public void setRefreshTime(int refreshTime) {
		this.refreshTime = refreshTime;
	}

	protected byte[] getData() {
		byte[] src = packet.getData();
		byte[] p = new byte[packet.getLength()]; // 根据报文长度，重建buf
		for (int i = 0; i < packet.getLength(); i++)
			p[i] = src[i];
		return p;
	}

	private void init_socket() throws Exception {
		socket = new DatagramSocket();
		socket.setSoTimeout(500);
	}

	private DatagramPacket create_packet(InetAddress addr, int port) {
		byte buf[] = new byte[65507];
		return new DatagramPacket(buf, buf.length, addr, port);
	}

	private void destroy() {
		socket.close();
	}

	protected void send_recv() throws Exception {
		this.init_socket();
		packet = this.create_packet(serverAddr, port);

		socket.send(packet);
		socket.receive(packet);

		if (this.broadcastEnabled) {
			DatagramPacket pkt = this.create_packet(mcaddr, mcport);
			pkt.setData(this.getData()); // 调用本类getData()函数，处理buf的大小
			socket.send(pkt);
		}

		this.destroy();
	}

}
